package com.suray.system.run.rgv;

import com.suray.system.run.core.*;
import com.suray.system.run.data.DeviceTaskInformation;
import com.suray.system.run.data.RgvInformation;
import com.suray.system.run.data.mysql.analyze.MonitorDataStore;
import com.suray.system.run.util.ExecTaskTime;
import com.suray.wcs.res.enums.RgvStatus;
import com.suray.wcs.service.enums.TaskType;
import com.suray.wcs.service.pojo.Rgv;

import java.util.Date;

public class RgvMonitorAction {
    /**
     * 小车对象
     */
    private Rgv rgv;

    /**
     * 小车监控信息
     */
    private RgvInformation rgvInformation;

    /**
     * 小车数据存储对象
     */
    private MonitorDataStore monitorDataStore;

    public RgvMonitorAction(Rgv rgv, RgvInformation rgvInformation, MonitorDataStore monitorDataStore) {
        this.rgv = rgv;
        this.rgvInformation = rgvInformation;
        this.monitorDataStore = monitorDataStore;
    }

    public void init() {
        rgvInformation.setErrorDescription(monitorDataStore.findErrorDesData(rgv.getSeries()));
        rgvInformation.setDeviceTaskInformation(monitorDataStore.findDeviceTaskInfoData(rgv.getSeries()));
        rgvInformation.setExecTaskTime(monitorDataStore.findExecTaskData(rgv.getSeries()));
        rgvInformation.setOffLineDescription(monitorDataStore.findOffLineDesData(rgv.getSeries()));
        rgvInformation.setLowBatteryDescription(monitorDataStore.findLowBatteryData(rgv.getSeries()));
        checkInitData();
    }

    /**
     * 初始化小车数据
     */
    private void checkInitData() {
        checkDeviceTaskInitData();
        checkExecTaskInitData();
    }

    /**
     * 小车任务初始化数据
     */
    private void checkDeviceTaskInitData() {
        DeviceTaskInformation deviceTaskInformation = rgvInformation.getDeviceTaskInformation();

        Date date = new Date(System.currentTimeMillis());
        if (!deviceTaskInformation.checkDate(date)) {
            deviceTaskInformation.clearExecTodayTaskTime();
            deviceTaskInformation.setCurDate(date);
            monitorDataStore.updateDeviceTaskInfoData(rgv.getSeries());
        }
    }

    /**
     * 小车当前执行数据初始化
     */
    private void checkExecTaskInitData() {
        rgvTaskMonitor(rgv, rgvInformation);
    }

    public void run() {
        rgvMonitor(rgv, rgvInformation);
        rgvTaskMonitor(rgv, rgvInformation);
    }

    /**
     * 小车任务信息监控
     * @param rgv
     * @param rgvInformation
     */
    private void rgvTaskMonitor(Rgv rgv, RgvInformation rgvInformation) {
        checkDeviceTaskInitData();

        if (rgvInformation.getExecTaskTime() == null) {
            //小车目前尚未检测到任务，进行任务检测
            if (rgv.getCurTask() != null) {
                //小车检测到任务
                initExecTaskTime(rgvInformation, rgv.getCurTask().getTaskId(), rgv.getCurTask().getTaskType());
            }
        } else if (rgvInformation.getExecTaskTime() != null) {
            //小车目前检测到任务，进行任务跟踪
            if (rgv.getCurTask() != null) {
                //小车有正在执行的任务
                if (rgv.getCurTask().getTaskId().equals(rgvInformation.getExecTaskTime().getTaskId())) {
                    //同一个任务
                } else {
                    //不是同一个任务，任务做结束处理
                    endExecTaskTime(rgvInformation);
                }
            } else {
                //小车没有正在执行的任务
                endExecTaskTime(rgvInformation);
            }
        }
    }

    /**
     * 结束任务
     * @param rgvInformation
     */
    private void endExecTaskTime(RgvInformation rgvInformation) {
        rgvInformation.getExecTaskTime().setEndTime(new Date(System.currentTimeMillis()));
        monitorDataStore.updateExecTaskData(rgv.getSeries());
        long taskTime = rgvInformation.getExecTaskTime().getExecTaskTime();
        rgvInformation.getDeviceTaskInformation().addExecTodayTaskTime(taskTime);
        rgvInformation.getDeviceTaskInformation().addExecAllTaskTime(taskTime);
        rgvInformation.setExecTaskTime(null);
        monitorDataStore.updateDeviceTaskInfoData(rgv.getSeries());
    }

    /**
     * 初始化任务信息
     * @param rgvInformation
     * @param taskType
     */
    private void initExecTaskTime(RgvInformation rgvInformation, int taskId, TaskType taskType) {
        ExecTaskTime execTaskTime = monitorDataStore.createExecTaskData(rgv.getSeries());
        execTaskTime.setExecTime(new Date(System.currentTimeMillis()));
        execTaskTime.setTaskId(taskId);
        execTaskTime.setTaskType(taskType);
        monitorDataStore.updateExecTaskData(rgv.getSeries());
        rgvInformation.setExecTaskTime(execTaskTime);

        rgvInformation.getDeviceTaskInformation().addExecTaskNum();
        monitorDataStore.updateDeviceTaskInfoData(rgv.getSeries());
    }

    /**
     * 小车监控
     * @param rgv
     * @param rgvInformation
     */
    private void rgvMonitor(Rgv rgv, RgvInformation rgvInformation) {
        analyzeNormalInformation(rgv, rgvInformation.getRgvInfo());
        analyzeErrorInformation();
        analyzeOfflineInformation();
        analyzeLowBatteryInformation();
        analyzeChargeInformation();
//        analyzeDodgeInformation(rgv, rgvInformation.getDodgeInfo());
    }

    /**
     * 处理常规信息
     * @param rgv
     * @param rgvInfo
     */
    private void analyzeNormalInformation(Rgv rgv, RgvInfo rgvInfo) {
        rgvInfo.setCurrentNode(rgv.getCurLocation());
        rgvInfo.setSoc(rgv.getBattery());
//        rgvInfo.setSpeed(rgv.get);
        rgvInfo.setDirection(rgv.getDirection());
        rgvInfo.setReverseStatus(rgv.getDirectionStatus());
        rgvInfo.setGroundCode(rgv.getGroundCode());
        rgvInfo.setPalletStatus(rgv.getPalletStatus());

        //TODO 避让次数
    }

    /**
     * 处理故障信息
     */
    private void analyzeErrorInformation() {
        ErrorDescription errorDescription = rgvInformation.getErrorDescription();

        if (errorDescription != null) {
            if (rgv.getRgvStatus() == RgvStatus.READY) {
                errorDescription.setEndErrorTime(new Date(System.currentTimeMillis()));
                monitorDataStore.updateErrorDesData(rgv.getSeries());
                rgvInformation.setErrorDescription(null);
            }
        } else {
            if (rgv.getRgvStatus() == RgvStatus.ERROR) {
                if (errorDescription == null) {
                    errorDescription = monitorDataStore.createErrorDesData(rgv.getSeries());
//                    errorDescription.setErroring(true);
                    errorDescription.setErrorTime(new Date(System.currentTimeMillis()));
                    errorDescription.setErrorLocation(rgv.getCurLocation().toString());
                    errorDescription.setErrorMessage(rgv.getErrorMessage());
                    if (rgv.getCurTask() != null) {
                        errorDescription.setErrorTaskId(rgv.getCurTask().getTaskId().toString());
                    }
                    monitorDataStore.updateErrorDesData(rgv.getSeries());
                    rgvInformation.setErrorDescription(errorDescription);
                }
            }
        }
    }

    /**
     * 处理离线信息
     */
    private void analyzeOfflineInformation() {
        OfflineDescription offLineDescription = rgvInformation.getOffLineDescription();

        if (offLineDescription != null) {
            if (rgv.getRgvStatus() != RgvStatus.OFF_LINE) {
                offLineDescription.setOffLineEndDate(new Date(System.currentTimeMillis()));
                monitorDataStore.updateOffLineDesData(rgv.getSeries());
            }

            if (offLineDescription.getOffLineEndDate() != null) {
                rgvInformation.setOffLineDescription(null);
            }
        } else {
            if (rgv.getRgvStatus() == RgvStatus.OFF_LINE) {
                OfflineDescription offlineDescription = monitorDataStore.createOffLineDesData(rgv.getSeries());
                offlineDescription.setOffLineStartDate(new Date(System.currentTimeMillis()));
                monitorDataStore.updateOffLineDesData(rgv.getSeries());
                rgvInformation.setOffLineDescription(offlineDescription);
            }
        }

    }

    /**
     * 处理低电量信息
     */
    private void analyzeLowBatteryInformation() {
        if (rgv.getBattery() == null) {
            return;
        }

        LowBatteryDescription lowBatteryDescription = rgvInformation.getLowBatteryDescription();

        if (lowBatteryDescription == null) {
            if (rgv.getBattery() < rgv.getRgvDB().getAlarmBatterySize()) {
                lowBatteryDescription = monitorDataStore.createLowBatteryData(rgv.getSeries());
                lowBatteryDescription.setBatSoc(rgv.getBattery());
                lowBatteryDescription.setMarkLowSoc(rgv.getRgvDB().getAlarmBatterySize());
                monitorDataStore.updateLowBatteryData(rgv.getSeries());
                rgvInformation.setLowBatteryDescription(lowBatteryDescription);
            }
        } else {
            if (rgv.getBattery() > rgv.getRgvDB().getAlarmBatterySize()) {
                lowBatteryDescription.setRecoverTime(new Date(System.currentTimeMillis()));
                monitorDataStore.updateLowBatteryData(rgv.getSeries());
                rgvInformation.setLowBatteryDescription(null);
            }
        }
    }

    /**
     * 处理充电信息
     */
    private void analyzeChargeInformation() {
        ChargeInfo chargeInfo = rgvInformation.getChargeInfo();

        if (chargeInfo != null) {
            if (rgv.getRgvStatus() != RgvStatus.CHARGING) {
                chargeInfo.setChargeEndTime(new Date(System.currentTimeMillis()));
                chargeInfo.setChargeEndSoc(rgv.getBattery());
                monitorDataStore.updateChargeInfoData(rgv.getSeries());
                rgvInformation.setChargeInfo(null);
            }
        } else {
            if (rgv.getRgvStatus() == RgvStatus.CHARGING) {
                chargeInfo = monitorDataStore.createChargeInfoData(rgv.getSeries());
                chargeInfo.setChargeStartSoc(rgv.getBattery());
                monitorDataStore.updateChargeInfoData(rgv.getSeries());
                rgvInformation.setChargeInfo(chargeInfo);
            }
        }
    }

    /**
     * 处理避让信息
     * @param rgv
     * @param dodgeInfo
     */
    private void analyzeDodgeInformation(Rgv rgv, DodgeInfo dodgeInfo) {

    }
}
